package xyz.ibenben.zhongdian.common.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * Date工具类
 * 处理时间的工具类，包含根据所给日期获取当天的00:00:00、根据所给日期获取当天的23:59:59等方法
 * 项目内所有和时间有关的方法都出自此类
 *
 * @author chenjian
 * @since 2017年10月18日下午5:17:22
 */
public class DateUtils {
    private DateUtils(){}

	/**
	 * 根据所给日期获取当天的00:00:00
	 * 
	 * @param date 参数
	 * @return 返回值
	 */
	public static Date getStartDate(Date date) {
		if (date != null) {
			Calendar cal = Calendar.getInstance();
			cal.setTime(date);
			cal.set(Calendar.HOUR_OF_DAY, 0);
			cal.set(Calendar.MINUTE, 0);
			cal.set(Calendar.SECOND, 0);
			return cal.getTime();
		}
		return null;
	}

	/**
	 * 根据所给日期获取当天的23:59:59
	 * 
	 * @param date 参数
	 * @return 返回值
	 */
	public static Date getEndDate(Date date) {
		if (date != null) {
			Date startDate = getStartDate(date);
			Calendar cal = Calendar.getInstance();
			cal.setTime(startDate);
			cal.add(Calendar.HOUR_OF_DAY, 23);
			cal.add(Calendar.MINUTE, 59);
			cal.add(Calendar.SECOND, 59);
			return cal.getTime();
		}
		return null;
	}

	/**
	 * 根据所给日期获取30天后的日期
	 * 
	 * @param date 参数
	 * @return 返回值
	 */
	public static Date getNextMonthDate(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.DAY_OF_MONTH, 30);
		return cal.getTime();
	}

	/**
	 * 取得指定月份的最后一天
	 * 
	 * @param date 参数
	 * @return 返回值
	 */
	public static int getMonthEnd(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.getActualMaximum(Calendar.DAY_OF_MONTH);
	}

	/**
	 * 取得当月的日
	 * 
	 * @param date 参数
	 * @return 返回值
	 */
	public static int getNowDay(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.get(Calendar.DATE);// 获取日
	}

	/**
	 * 获取上个月的日期
	 * 
	 * @param date 参数
	 * @return 返回值
	 */
	public static Date getLastMonth(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.MONTH, -1);
		return cal.getTime();
	}

	/**
	 * 获取下个月的第一天
	 * 
	 * @param date 参数
	 * @return 返回值
	 */
	public static Date getNextMonthFirstDay(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.MONTH, 1);
		cal.set(Calendar.DATE, 1);
		return cal.getTime();
	}

	/**
	 * 获取下个月的最后一天
	 * 
	 * @param date 参数
	 * @return 返回值
	 */
	public static Date getNextMonthLastDay(Date date) {
		Date lastMonth = getNextMonthFirstDay(date);
		Calendar cal = Calendar.getInstance();
		cal.setTime(lastMonth);
		cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DATE));
		return cal.getTime();
	}

	/**
	 * 获取当前的时间
	 *
	 * @param date 日期
	 * @param format 参数
	 * @return 返回值
	 */
	public static String getCurrentTime(Date date, String format) {
		Date newDate = new Date();
		if (date != null) {
			newDate = date;
		}
		return new SimpleDateFormat(format).format(newDate);
	}

	/**
	 * 获取前一天日期
	 * 
	 * @param format 参数
	 * @return 返回值
	 */
	public static String getYestoday(String format) {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DATE, -1);
		return new SimpleDateFormat(format).format(calendar.getTime());
	}

	/**
	 * 功能：将制定日期的秒数进行重新设置。
	 *
	 * @param date 日期
	 * @param second 秒数
	 * @return 设置后的日期
	 */
	public static Date setSecondNew(Date date, int second) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.SECOND, second);
		return new Date(c.getTimeInMillis());
	}

	/**
	 * 功能：将制定日期的分钟进行重新设置。
	 *
	 * @param date 日期
	 * @param minute 分钟数
	 * @return 设置后的日期
	 */
	public static Date setMinuteNew(Date date, int minute) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.MINUTE, minute);
		return new Date(c.getTimeInMillis());
	}

	/**
	 * 功能：将制定日期的小时进行重新设置。
	 * @param date 参数
	 * @param hour 参数
	 * @return 返回值
	 */
	public static Date setHourNew(Date date, int hour) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.HOUR_OF_DAY, hour);
		return new Date(c.getTimeInMillis());
	}

	/**
	 * 功能：将制定日期的天进行重新设置。
	 * @param date 参数
	 * @param day 参数
	 * @return 返回值
	 */
	public static Date setDayNew(Date date, int day) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.DATE, day);
		return new Date(c.getTimeInMillis());
	}

	/**
	 * 功能：将制定日期的月进行重新设置。
	 * @param date 参数
	 * @param month 参数
	 * @return 返回值
	 */
	public static Date setMonthNew(Date date, int month) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.MONTH, month - 1);
		return new Date(c.getTimeInMillis());
	}

	/**
	 * 功能：将制定日期的年进行重新设置。
	 * @param date 参数
	 * @param year 参数
	 * @return 返回值
	 */
	public static Date setYearNew(Date date, int year) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.YEAR, year);
		return new Date(c.getTimeInMillis());
	}

	/**
	 * 功能：得到制定月有多少天。
	 *
	 * @param date
	 * @return int
	 */
	public static int daysNumOfMonth(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.getActualMaximum(Calendar.DATE);
	}

	/**
	 * 将yyyy-MM-dd HH:mm:ss字符串转换成日期
	 * 
	 * @param dateStr yyyy-MM-dd HH:mm:ss字符串
	 * @param format 格式
	 * @return net.maxt.util.Date 日期 ,转换异常时返回null。
	 */
	public static Date parseDate(String dateStr, String format) {
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		try {
			Date d = sdf.parse(dateStr);
			return new Date(d.getTime());
		} catch (ParseException e) {
			return null;
		}
	}

	/**
	 * 功能：计算两个时间的时间差。
	 * 
	 * @param time 另一个时间。
	 * @return Timespan 时间间隔
	 */
	public static long substract(Date time) {
		return new Date().getTime() - time.getTime();
	}

	/**
	 * 功能：制定时间增加秒数。
	 *
	 * @param date 日期
	 * @param seconds 正值时时间延后，负值时时间提前。
	 * @return Date
	 */
	public static Date addSeconds(Date date, int seconds) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.SECOND, c.get(Calendar.SECOND) + seconds);
		return new Date(c.getTimeInMillis());
	}

	/**
	 * 功能：制定时间增加分钟数。
	 *
	 * @param date 日期
	 * @param minutes 正值时时间延后，负值时时间提前。
	 * @return Date
	 */
	public static Date addMinutes(Date date, int minutes) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.MINUTE, c.get(Calendar.MINUTE) + minutes);
		return new Date(c.getTimeInMillis());
	}

	/**
	 * 功能：制定时间增加小时数。
	 *
	 * @param date 日期
	 * @param hours 正值时时间延后，负值时时间提前。
	 * @return Date
	 */
	public static Date addHours(Date date, int hours) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.HOUR, c.get(Calendar.HOUR) + hours);
		return new Date(c.getTimeInMillis());
	}

	/**
	 * 功能：制定时间增加天数。
	 *
	 * @param date 日期
	 * @param days 正值时时间延后，负值时时间提前。
	 * @return Date
	 */
	public static Date addDays(Date date, int days) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.DATE, c.get(Calendar.DATE) + days);
		return new Date(c.getTimeInMillis());
	}

	/**
	 * 功能：制定时间增加月数。
	 *
	 * @param date 日期
	 * @param months 正值时时间延后，负值时时间提前。
	 * @return Date
	 */
	public static Date addMonths(Date date, int months) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.MONTH, c.get(Calendar.MONTH) + months);
		return new Date(c.getTimeInMillis());
	}

	/**
	 * 功能：制定时间增加年数。注意遇到2月29日情况，系统会自动延后或者减少一天。
	 *
	 * @param date 日期
	 * @param years 正值时时间延后，负值时时间提前。
	 * @return Date
	 */
	public static Date addYears(Date date, int years) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.YEAR, c.get(Calendar.YEAR) + years);
		return new Date(c.getTimeInMillis());
	}

	/**
	 * 根据制定日期得到星期几,得到数字。
	 * 7, 1, 2, 3, 4, 5, 6
	 * @param date 日期
	 * @return Integer 如：6
	 */
	public static int dayOfWeekInt(Date date) {
		Integer[] dayNames = { 7, 1, 2, 3, 4, 5, 6 };
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;
		if (dayOfWeek < 0)
			dayOfWeek = 0;
		return dayNames[dayOfWeek];
	}

	/**
	 * 根据日期返回对应corn表达式字符串
	 * 例如 0 58 11 2 4 ? 2018
	 * @param date 日期
	 * @return 根据日期返回corn
	 */
	public static String translation(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		int year = calendar.get(Calendar.YEAR);
		int month = calendar.get(Calendar.MONTH) + 1;
		int day = calendar.get(Calendar.DATE);
		int hour = calendar.get(Calendar.HOUR);
		int min = calendar.get(Calendar.MINUTE);
		int second = calendar.get(Calendar.SECOND);
		return second + " " + min + " " + hour + " " + day + " " + month + " ? " + year;
	}
}
